<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>
	<script type="text/javascript">
		// function foo(){
		// 	var arr = [];
		// 	for(var i = 0;i < 10;i++){
		// 		arr[i] = (function(n){
		// 			return function(){
		// 				return n;
		// 			}
		// 		})(i)
		// 	}
		// 	return arr
		// }
		// var bar = foo();
		// console.log(bar[5]());
		
	</script>
	
	<script type="text/javascript">
// 闭包的十种表现形式
	// 1、返回值 最常见的一种形式
		// var fn = function(){
		// 	name = 'fyr';
		// 	return function(){
		// 		return name;
		// 	}
		// }
		// var fnc = fn();
		// console.log(fnc());
	// 2、函数赋值 一种变形的形式是将内部的函数赋值给另一个外部的变量
		// var fn2;
		// var fn = function(){
		// 	name = 'fyr';
		// 	var a = function(){
		// 		return name;
		// 	}
		// 	fn2 = a
		// 	}
		// fn() // 相当于给fn2赋值  下一步执行 
		// console.log(fn2());
	// 3、函数参数
		var fn2 = function(f){
			console.log(f());
		}
		function fn(){
			var name = 'fyr';
			var a = function(){
				return name;
			}
			fn2(a)
		}
		fn();
	// 4、 IIFE
		function fn3(f){
			console.log(f())
		}
		(function(){
			var name = 'xr'
			var a = function(){
				return name;
			}
			fn3(a)
		})();
	// 5、循环赋值：
	console.log('-----------------------5------------------------');
		function foo(){
			var arr = [];
			for(var i = 0;i < 10; i++){
				arr[i] = (function(n){
					return function(){
						return n;
					}
				})(i);
			}
			return arr;
		}
		var bar = foo();
		console.log(bar[0]());
	// 6、 getter setter
	console.log('-----------------------6------------------------');
		var getValue,setValue;
		(function(){
			var num = 0;
			getValue = function(){
				return num;
			}
			setValue = function(n){
				num = n;
				return num;
			}
		})()
		console.log(getValue());
		setValue(10)
		console.log(getValue());
	// 7、 迭代器 类似于计数器
	console.log('-----------------------7------------------------');
		// var add = function(){
		// 	var num = 0;
		// 	return function(){
		// 		return num++;
		// 	}
		// }()
		// console.log(add());
		// console.log(add());
		
		function setUp(arr){
			var i = 0;
			return function(){
				return arr[i++];
			}
		}
		var next = setUp([1,2,3,4,5])
		console.log(next());
	// 8、 区分首次
	console.log('-----------------------8------------------------');
	var first = (function(){
		var list = [];
		return function(num){
			if(list.indexOf(num) >= 0){
				return false;
			}else{
				list.push(num)
				return true;
			}
		}
	})();
	console.log(first(1));
	console.log(first(1));
	// 9、 缓存机制。
	console.log('-----------------------9------------------------');
		// 9.1 未加入缓存。
		// function mult(){
		// 	var sum = 0;
		// 	for(var i = 0; i<arguments.length;i++){
		// 		sum = sum + arguments[i]
		// 	}
		// 	return sum
		// }
		// console.log(mult(1,2,3,4,5,6));
		// 9.2 有缓存。 模拟一个对象的key 将key和valu一一对应起来。
		var mult = function(){
			var cache = {}
			var calculate = function(){
				var sum = 0;
					for(var i = 0; i<arguments.length;i++){
						sum = sum + arguments[i]
					}
					return sum
			}
			return function(){
				var arr = Array.prototype.join.call(arguments,',')
				if(arr in cache){
					return cache[arr]
				}
				return cache[arr] = calculate.apply(null,arguments)
			}
		}();
		console.log(mult(1,2,3,4,5,6));
	// 10、 图片上报。
	console.log('-----------------------10------------------------');
		var report = function(src){
			var img = new Image(){
				img.src = src
			}
		}
		report('https://www.baiud.com/userinfo/img')
		var report = function(src){
			var imgs = [];
			return function(){
				var img = new Image(){
					img.push(img);
				img.src = src
				}
			}	
		}
	</script>
</html>
